use anyhow::bail;
use axum::body::Bytes;
use reqwest::multipart;
use serde_json::{json, Value};
use std::{borrow::Cow, fs};

// 获取微信的token
pub async fn get_mp_access_token(app_id: &str, app_secret: &str) -> anyhow::Result<String> {
    let url = format!(
        "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}",
        app_id, app_secret
    );

    let resp = reqwest::get(url).await?;
    let body = resp.text().await?;
    let json_data: Value = serde_json::from_str(&body)?;
    let access_token = &json_data["access_token"];
    if access_token == &Value::Null {
        let err_msg = format!(
            "get access token error,error info is {{code:{} msg:{}}}",
            json_data["errcode"], json_data["errmsg"]
        );
        bail!(err_msg)
    }
    let token = access_token.as_str().unwrap();
    Ok(token.to_string())
}

// 获取微信小程序的小程序码不限制数量
pub async fn get_miniapp_qrcode(token: &str, content: String) -> anyhow::Result<Bytes> {
    let url = format!(
        "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={}",
        token
    );
    let client = reqwest::Client::new();
    let resp = client
        .post(url)
        .json(&json!({"scene":content,"page":"pages/identcode/index"}))
        .send()
        .await?;
    let body = resp.bytes().await?;
    Ok(body)
}
// 获取小程序码，限制数量，保存到微信公众平台。
pub async fn get_miniapp_qrcode_limit(token: &str, path:String) -> anyhow::Result<Bytes> {
    let url = format!(
        "https://api.weixin.qq.com/wxa/getwxacode?access_token={}",
        token
    );
    let client = reqwest::Client::new();
    let resp = client
        .post(url)
        .json(&json!({"path":path}))
        .send()
        .await?;
    let body = resp.bytes().await?;
    Ok(body)
}
// 公众号临时素材上传
pub async fn upload_gzh_image(token: &str, image: &str) -> anyhow::Result<String> {
    let url = format!(
        "https://api.weixin.qq.com/cgi-bin/media/upload?access_token={}&type=image",
        token
    );
    let filebyte = fs::read(image)?;
    let filepart = multipart::Part::bytes(Cow::from(filebyte)).file_name("mp_qrcode.png");
    let form = multipart::Form::new().part("media", filepart);

    let client = reqwest::Client::new();
    let resp = client.post(url).multipart(form).send().await?;
    let body = resp.text().await?;
    let json_data: Value = serde_json::from_str(&body)?;
    let media_id = &json_data["media_id"];
    if media_id == &Value::Null {
        let err_msg = format!(
            "upload gzh image error,error info is {{code:{} msg:{}}}",
            json_data["errcode"], json_data["errmsg"]
        );
        bail!(err_msg)
    }
    let media_id = media_id.as_str().unwrap();
    Ok(media_id.to_string())
}
// 公众号永久图片素材上传
pub async fn upload_gzh_image_v2(token: &str, image: &str,image_code:i32) -> anyhow::Result<String> {
    let url = format!(
        "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={}&type=image",
        token
    );
    let filebyte = fs::read(image)?;
    let file_name = match image_code {
        10001=>"qrcode_vcode.png",
        10002=>"qrcode_icode.png",
        _=>"mp_qrcode.png",
    };
    let filepart = multipart::Part::bytes(Cow::from(filebyte)).file_name(file_name);
    let form = multipart::Form::new().part("media", filepart);

    let client = reqwest::Client::new();
    let resp = client.post(url).multipart(form).send().await?;
    let body = resp.text().await?;
    let json_data: Value = serde_json::from_str(&body)?;
    let media_id = &json_data["media_id"];
    if media_id == &Value::Null {
        let err_msg = format!(
            "upload gzh image error,error info is {{code:{} msg:{}}}",
            json_data["errcode"], json_data["errmsg"]
        );
        bail!(err_msg)
    }
    let media_id = media_id.as_str().unwrap();
    Ok(media_id.to_string())
}